package cn.edu.tju.core.security.controller;

import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.rest.dto.LoginDto;
import cn.edu.tju.core.security.rest.dto.PasswordDTO;
import cn.edu.tju.core.security.rest.dto.RegisterDTO;
import cn.edu.tju.core.security.service.UserProfileService;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.elm.common.response.HttpResult;
import cn.edu.tju.elm.exception.MethodArgumentNotValidException;
import cn.edu.tju.elm.model.DTO.UserDTO;
import cn.edu.tju.elm.service.VirtualWalletService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@Tag(name = "用户管理", description = "提供用户注册、登录信息查询、密码修改、头像更新等操作")
@RequiredArgsConstructor
@Slf4j
public class UserRestController {

    private final AuthenticationRestController authenticationRestController;
    private final UserService userService;
    private final UserProfileService userProfileService;
    private final VirtualWalletService virtualWalletService;

    @PostMapping("/register")
    @Operation(
            summary = "用户注册",
            description = "注册新用户，支持普通用户和商家类型，注册成功后会自动创建虚拟钱包"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "注册成功"),
            @ApiResponse(responseCode = "400", description = "用户名已存在或请求参数无效")
    })
    public HttpResult<String> register(
            @Parameter(description = "用户注册信息", required = true,
                    examples = @ExampleObject(
                            value = """
                                {
                                    "username": "testuser",
                                    "password": "password123",
                                    "type": 0
                                }
                            """
                    ))
            @RequestBody RegisterDTO registerDTO) {
        try {
            User newUser = userService.registerUser(registerDTO);
            // 自动创建钱包
            virtualWalletService.createWalletForUser(newUser);
            return HttpResult.ok("注册成功");
        } catch (IllegalArgumentException e) {
            throw new MethodArgumentNotValidException(e.getMessage());
        }
    }

    @GetMapping("/user")
    @Operation(
            summary = "获取当前用户信息",
            description = "获取当前登录用户的基本信息、权限和资料（包括头像、简介等）"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public HttpResult<UserDTO> getCurrentUser() {
        UserDTO userDTO = userProfileService.getCurrentUserProfile();
        return HttpResult.ok(userDTO);
    }

    @PostMapping("/password")
    @Operation(
            summary = "管理员修改用户密码",
            description = "管理员可以修改任何用户的密码，无需验证旧密码"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "密码修改成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足，需要管理员权限"),
            @ApiResponse(responseCode = "404", description = "用户不存在")
    })
    @PreAuthorize("hasAuthority('ADMIN')")
    public HttpResult<String> updateUserPasswordByAdmin(
            @Parameter(description = "用户密码修改信息", required = true,
                    examples = @ExampleObject(
                            value = """
                                {
                                    "username": "testuser",
                                    "password": "newpassword123"
                                }
                            """
                    ))
            @RequestBody LoginDto loginDto) {
        userService.updatePassword(loginDto.getUsername(), loginDto.getPassword());
        return HttpResult.ok("密码修改成功");
    }

    @PostMapping("/password2")
    @Operation(
            summary = "用户修改自己的密码",
            description = "用户修改自己的密码，需要验证旧密码"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "密码修改成功"),
            @ApiResponse(responseCode = "400", description = "旧密码错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public HttpResult<String> updateCurrentUserPassword(
            @Parameter(description = "密码修改信息", required = true,
                    examples = @ExampleObject(
                            value = """
                                {
                                    "oldPassword": "oldpassword123",
                                    "newPassword": "newpassword456"
                                }
                            """
                    ))
            @RequestBody PasswordDTO passwordDTO) {
        User currentUser = userService.getUserWithAuthorities();

        // 验证旧密码
        LoginDto loginDto = LoginDto.builder()
                .password(passwordDTO.getOldPassword())
                .username(currentUser.getUsername())
                .rememberMe(false)
                .build();

        try {
            authenticationRestController.authorize(loginDto);
        } catch (BadCredentialsException e) {
            throw new MethodArgumentNotValidException("旧密码错误");
        }

        // 更新密码
        userService.updatePassword(currentUser.getUsername(), passwordDTO.getNewPassword());
        return HttpResult.ok("密码修改成功");
    }

    @PatchMapping("/users/avatar")
    @Operation(
            summary = "更新用户头像",
            description = "更新当前登录用户的头像URL"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "头像更新成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public HttpResult<UserDTO> updateAvatar(
            @Parameter(description = "用户头像信息", required = true,
                    examples = @ExampleObject(
                            value = """
                                {
                                    "avatarUrl": "https://example.com/avatar.jpg"
                                }
                            """
                    ))
            @RequestBody UserDTO userDTO) {
        UserDTO updatedUser = userProfileService.updateUserAvatar(userDTO.getAvatarUrl());
        return HttpResult.ok(updatedUser);
    }
}